package cn.hbads.test.task;

import cn.hbads.support.error.ErrorType;
import cn.hbads.support.http.client.HttpClientUtil;
import cn.hbads.support.http.client.model.HttpRequestModel;
import cn.hbads.support.http.client.model.HttpResponseModel;
import cn.hbads.support.structure.result.ComputeResult;
import cn.hbads.test.context.TaskContextManager;
import cn.hbads.test.context.TaskMonitor;
import cn.hbads.test.model.TaskProcessModel;

/**
 * <b> 抽象单次HTTP请求响应处理任务 </b>
 *
 * @author : yvvb
 * @date : 2025/5/11
 */
public abstract class AbstractHttpRequestTask<T> implements ExecuteTask {
    private final String taskName;
    private final Class<?> expectResponseClass;

    public AbstractHttpRequestTask(String taskName, Class<T> expectResponseClass) {
        this.taskName = taskName;
        this.expectResponseClass = expectResponseClass;
    }

    @Override
    public String getTaskName() {
        return taskName;
    }

    @Override
    public boolean execute(TaskContextManager taskContextManager, TaskMonitor taskMonitor) {
        final HttpRequestModel requestModel = buildRequestModel(taskContextManager);
        final ComputeResult<? extends HttpResponseModel<?>, ErrorType> responseResult = HttpClientUtil.sendRequest(requestModel, expectResponseClass);
        if (responseResult.isSuccess()) {
            final HttpResponseModel<?> httpResponseModel = responseResult.get();
            taskMonitor.recordProcess(new TaskProcessModel());
            final var assertResult = assertResponse(httpResponseModel);
            assertResult.ifSuccessOrFail(
                    extraMsg -> taskMonitor.recordSuccess(this.getTaskName(), extraMsg),
                    failMsg -> taskMonitor.recordFailure(this.getTaskName(), failMsg)
            );
            return assertResult.isSuccess();
        } else {
            responseResult.ifFail(fail -> {
                taskMonitor.recordProcess(new TaskProcessModel());
                taskMonitor.recordFailure(this.getTaskName(), fail.getErrorMsg());
            });
            return false;
        }
    }

    protected abstract HttpRequestModel buildRequestModel(TaskContextManager taskContextManager);

    protected abstract ComputeResult<String, String> assertResponse(HttpResponseModel<?> httpResponseModel);

}
